﻿using AppFramework.Version;
using Abp.IdentityServer4vNext;
using Abp.Zero.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using AppFramework.Authorization.Delegation;
using AppFramework.Authorization.Roles;
using AppFramework.Authorization.Users;
using AppFramework.Chat;
using AppFramework.Editions;
using AppFramework.Friendships;
using AppFramework.MultiTenancy;
using AppFramework.MultiTenancy.Accounting;
using AppFramework.MultiTenancy.Payments;
using AppFramework.Storage;
using AppFramework.Demo;
using IdentityServer4.Validation;
using AppFramework.WorkOrderModels;
using AppFramework.DinosaursParkMes.DictionariesModel;
using AppFramework.DinosaursParkMes.Product;
using AppFramework.DinosaursParkMes.MaterialModel;
using AppFramework.DinosaursParkMes.Process;
using AppFramework.DinosaursParkMes.BOM;
using AppFramework.DinosaursParkMes.CodingRuleModel;
using AppFramework.DinosaursParkMes.ProductionPlanning;
using AppFramework.DinosaursParkMes.ProductionPlanningModel;
using AppFramework.DinosaursParkMes.TicketTask;
using AppFramework.DinosaursParkMes.Production;
using Microsoft.EntityFrameworkCore.Infrastructure;
using AppFramework.DinosaursParkMes.ProductionReturn;
using AppFramework.DinosaursParkMes.SingnalrModel;
using AppFramework.DinosaursParkMes.ReportForWork;
using AppFramework.DinosaursParkMes.ReportForWorker;

namespace AppFramework.EntityFrameworkCore
{
    public class AppFrameworkDbContext : AbpZeroDbContext<Tenant, Role, User, AppFrameworkDbContext>, IAbpPersistedGrantDbContext
    {
        public virtual DbSet<AbpDemo> AbpDemos { get; set; }

        public virtual DbSet<AbpVersion> AbpVersions { get; set; }

        /* Define an IDbSet for each entity of the application */

        public virtual DbSet<BinaryObject> BinaryObjects { get; set; }

        public virtual DbSet<Friendship> Friendships { get; set; }

        public virtual DbSet<ChatMessage> ChatMessages { get; set; }

        public virtual DbSet<SubscribableEdition> SubscribableEditions { get; set; }

        public virtual DbSet<SubscriptionPayment> SubscriptionPayments { get; set; }

        public virtual DbSet<Invoice> Invoices { get; set; }

        public virtual DbSet<PersistedGrantEntity> PersistedGrants { get; set; }

        public virtual DbSet<SubscriptionPaymentExtensionData> SubscriptionPaymentExtensionDatas { get; set; }

        public virtual DbSet<UserDelegation> UserDelegations { get; set; }

        public virtual DbSet<RecentPassword> RecentPasswords { get; set; }


        #region 工序管理
        public virtual DbSet<ProcessModel> ProcessModels { get; set; }//工序表
        public virtual DbSet<CraftRouteModel> CraftRouteModels { get; set; }//工艺路线
        public virtual DbSet<CraftProcessModel> CraftProcessModels { get; set; }//工艺路线子表
        #endregion
        #region 字典管理
        public virtual DbSet<Dictionaries> Dictionaries { get; set; }//字典主表
        public virtual DbSet<Dictionarieslist> Dictionarieslist { get; set; }//字典信息表
        #endregion
        #region 物料管理
        public virtual DbSet<Material> Material { get; set; }//物料表
        public virtual DbSet<MaterialProductImg> MaterialProductImg { get; set; }//物料-产品-图片表
        public virtual DbSet<Materialtype> Materialtype { get; set; }//物料类型表
        #endregion
        #region BOM管理
        public virtual DbSet<BillOfMaterial> BillOfMaterial { get; set; }//BOM—物料清单
        public virtual DbSet<BillOfMaterialDetails> BillOfMaterialDetails { get; set; }//BOM_物料配件
        public virtual DbSet<ProcessMaterial> ProcessMaterial { get; set; }//BOM_工序物料
        #endregion
        #region 产品管理
        public virtual DbSet<Productinfo> Productinfos { get; set; }//产品表
        public virtual DbSet<ProductClassification> ProductClassifications { get; set; }//产品分类表
        #endregion
        #region 编号管理
        public virtual DbSet<Codingrules> Codingrules { get; set; } //编号规则
        public virtual DbSet<CodingRule> CodingRule { get; set; }//编号规则
        #endregion
        #region 生成计划管理
        public virtual DbSet<ProductionPlanning> ProductionPlanning { get; set; }//生产工单
        #endregion
        #region 工单任务管理
        public virtual DbSet<SendWorkinfo> SendWorkinfos { get; set; }//派工表
        public virtual DbSet<TeamorGroupinfo> TeamorGroupinfos { get; set; }//班组线
        public virtual DbSet<TicketTaskinfo> TicketTaskinfos { get; set; }//工单任务表
        public virtual DbSet<Memberinfo> Memberinfos { get; set; }//成员表
        #endregion
        #region 生产退料
        public virtual DbSet<ProductionReturninfo> ProductionReturninfos { get; set; }//派工表
        public virtual DbSet<ReturnofMaterialinfo> ReturnofMaterialinfos { get; set; }//派工表子表

        #endregion
        #region 通知公告
        public virtual DbSet<Announcement> Announcements { get; set; }
        public virtual DbSet<UserInfo> UserInfos { get; set; }
        #endregion
        #region 赋码管理
        public virtual DbSet<UniqueIdCode> UniqueIdCode { get; set; }//赋码管理
        #endregion
        #region 报工、质检
        public virtual DbSet<ReportOfWorker> ReportOfWorker { get; set; }//报工
        public virtual DbSet<QualityTesting> QualityTesting { get; set; }//质检
        #endregion

        public virtual DbSet<ProductionWordOrder> ProductionWordOrder { get; set; }//生产工单
        public virtual DbSet<ProductWorkModels> ProductWorkModels { get; set; }//生产工单

        public virtual DbSet<MaterialRequisition> MaterialRequisitions { get; set; }//领料主表
        public virtual DbSet<MaterialRequisitionBOM> MaterialRequisitionBOMs { get; set; }//领料BOM物料子表
        public AppFrameworkDbContext(DbContextOptions<AppFrameworkDbContext> options)
            : base(options)
        {

        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<AbpVersion>(a =>
            {
                a.HasIndex(e => new { e.TenantId });
            });
            modelBuilder.Entity<BinaryObject>(b =>
                       {
                           b.HasIndex(e => new { e.TenantId });
                       });
            //物料表
            modelBuilder.Entity<Material>(b =>
            {
                b.HasIndex(e => new { e.Name, e.Materialtype, e.State });
                b.HasIndex(e => new { e.Materialclassify });
                b.HasIndex(e => new { e.MaterialProperty });
            });
            //生成计划表
            modelBuilder.ApplyConfiguration(new ProductionPlanningMap());
            modelBuilder.Entity<ChatMessage>(b =>
            {
                b.HasIndex(e => new { e.TenantId, e.UserId, e.ReadState });
                b.HasIndex(e => new { e.TenantId, e.TargetUserId, e.ReadState });
                b.HasIndex(e => new { e.TargetTenantId, e.TargetUserId, e.ReadState });
                b.HasIndex(e => new { e.TargetTenantId, e.UserId, e.ReadState });
            });
            //赋码管理表
            modelBuilder.ApplyConfiguration(new UniqueIdCodeMap());
            modelBuilder.Entity<UniqueIdCode>(b =>
            {
                b.HasIndex(e => new { e.Barcodetype });
                b.HasIndex(e => new { e.State });
            });
            modelBuilder.Entity<Friendship>(b =>
            {
                b.HasIndex(e => new { e.TenantId, e.UserId });
                b.HasIndex(e => new { e.TenantId, e.FriendUserId });
                b.HasIndex(e => new { e.FriendTenantId, e.UserId });
                b.HasIndex(e => new { e.FriendTenantId, e.FriendUserId });
            });

            modelBuilder.Entity<Tenant>(b =>
            {
                b.HasIndex(e => new { e.SubscriptionEndDateUtc });
                b.HasIndex(e => new { e.CreationTime });
            });

            modelBuilder.Entity<SubscriptionPayment>(b =>
            {
                b.HasIndex(e => new { e.Status, e.CreationTime });
                b.HasIndex(e => new { PaymentId = e.ExternalPaymentId, e.Gateway });
            });

            modelBuilder.Entity<SubscriptionPaymentExtensionData>(b =>
            {
                b.HasQueryFilter(m => !m.IsDeleted)
                    .HasIndex(e => new { e.SubscriptionPaymentId, e.Key, e.IsDeleted })
                    .IsUnique();
            });

            modelBuilder.Entity<UserDelegation>(b =>
            {
                b.HasIndex(e => new { e.TenantId, e.SourceUserId });
                b.HasIndex(e => new { e.TenantId, e.TargetUserId });
            });
            //产品表
            modelBuilder.Entity<Productinfo>(b =>
            {
                b.HasIndex(e=>new {e.Productid });
                b.HasIndex(e => new { e.Producttype });
                b.HasIndex(e => new {  e.Productproperty });
                b.HasIndex(e => new { e.Productclassid });
            });
            //BOM
            modelBuilder.Entity<BillOfMaterial>(b =>
            {
                b.HasIndex(e => new { e.Versionnumber, e.Numberbom, e.Productname, e.Productmodel, e.Productnumber });
                b.Property(e => e.Versionnumber).IsRequired().HasMaxLength(50);
                b.Property(e => e.Numberbom).IsRequired().HasMaxLength(50);
                b.Property(e => e.Productname).IsRequired().HasMaxLength(50);
                b.Property(e => e.Productmodel).IsRequired().HasMaxLength(50);
                b.Property(e => e.Productnumber).IsRequired().HasMaxLength(50);
            });
            //报工
            modelBuilder.Entity<ReportOfWorker>(b =>
            {
                b.HasIndex(e => new { e.WorkNumber,e.ReportWorkerNumber });
                b.Property(e =>e.ReportWorkerNumber).IsRequired().HasMaxLength(50);
            });
            //质检
            modelBuilder.Entity<QualityTesting>(b =>
            {
                b.HasIndex(e => new { e.QualityNumber, e.ReportWorkerNumber });
                b.Property(e => e.QualityNumber).IsRequired().HasMaxLength(50);
            });
            modelBuilder.ConfigurePersistedGrantEntity();
            
            //工序表
            modelBuilder.Entity<ProcessModel>(b =>
            {
                b.Property(x => x.Processname).IsRequired().HasMaxLength(50);
                b.Property(x => x.Processcode).IsRequired().HasMaxLength(50);
                b.Property(x => x.Processstate).IsRequired().HasMaxLength(50);
                b.HasIndex(x => new { x.Processname ,x.Processstate});
                b.HasIndex(x => new { x.Processcode });

            });
            //工艺路线表
            modelBuilder.Entity<CraftRouteModel>(b =>
            {
                b.Property(x => x.Routecoded).IsRequired().HasMaxLength(50);
                b.Property(x => x.Routename).IsRequired().HasMaxLength(50);
                b.Property(x => x.Routestate).IsRequired().HasMaxLength(50);
                b.HasIndex(x => new { x.Routecoded, x.Routename });
                b.HasIndex(x => new { x.Routestate });

            });

            //工艺路线字表
            modelBuilder.Entity<CraftProcessModel>(b =>
            {
                b.Property(x => x.Serialnumber).IsRequired();
                b.Property(x => x.Craftcode).IsRequired().HasMaxLength(50);
                b.Property(x => x.Process).IsRequired().HasMaxLength(50);
                b.Property(x => x.Keyprocess).IsRequired().HasMaxLength(50);

            });
            //领料主表
            modelBuilder.Entity<MaterialRequisition>(b =>
            {
                b.Property(x => x.Materialrequisitionname).IsRequired().HasMaxLength(50);
                b.Property(x => x.Materialrequisitioncode).IsRequired().HasMaxLength(255);
                b.Property(x => x.Materialrequisitiondate).IsRequired();
                b.Property(x => x.Person).IsRequired().HasMaxLength(50);
                b.Property(x => x.Workordername).IsRequired().HasMaxLength(50);
                b.Property(x => x.Workordercode).IsRequired().HasMaxLength(255);
                b.Property(x => x.Taskname).IsRequired().HasMaxLength(50);
                b.Property(x => x.Taskcode).IsRequired().HasMaxLength(255);
                b.HasIndex(x => new { x.Materialrequisitionname, x.Materialrequisitioncode });
                b.HasIndex(x => new { x.Workordername, x.Workordercode });
                b.HasIndex(x => new { x.Materialrequisitiondate });
            });
            //领料BOM物料子表
            modelBuilder.Entity<MaterialRequisitionBOM>(b =>
            {
                b.Property(x => x.Serialnumber).IsRequired();
                b.Property(x => x.Materialrequisitioncode).IsRequired().HasMaxLength(255);
                b.Property(x => x.Materialname).IsRequired().HasMaxLength(50);
                b.Property(x => x.Materialcode).IsRequired().HasMaxLength(255);
                b.Property(x => x.Specificationsandmodels).IsRequired().HasMaxLength(50);
                b.Property(x => x.Unit).IsRequired().HasMaxLength(10);
                b.Property(x => x.Stock).IsRequired();
                b.Property(x => x.Number).IsRequired();
                b.Property(x => x.Batchnumber).IsRequired().HasMaxLength(50);
                b.Property(x => x.Warehousename).IsRequired().HasMaxLength(50);
                b.Property(x => x.Storagelocationname).IsRequired().HasMaxLength(50);
            });
        }
    }
}